package com.qf.service;

import com.qf.config.IdWorker;
import com.qf.constant.CacheConstants;
import com.qf.constant.RabbitMQConstants;
import com.qf.constant.ReportStateConstants;
import com.qf.constant.SourceType;
import com.qf.feign.CacheFegin;
import com.qf.form.SmsInterfaceForm;
import com.qf.model.StandardSubmit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * projectName: wokepase1
 *
 * @author: 强力
 * time: 2021/10/16 15:08
 * description:
 */
@Service
@Slf4j
public class SmsInterfaceFormServiceImpl implements SmsInterfaceFormService{

    @Autowired
    private CacheFegin cacheFegin;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private IdWorker idWorker;
    @Override
    public Map<String, String> checkInterfaceForm(SmsInterfaceForm smsInterfaceForm) {
        Map<String,String> resultMap=new HashMap<>();

        //1校验clientID,根据这个redis中的数据进行查找校验
        String clientID = smsInterfaceForm.getClientID();
            //远程调用cache缓存模块从redis中获取客户端对象
        Map clientobj = cacheFegin.hMGet(CacheConstants.CACHE_PREFIX_CLIENT + clientID);

        if (clientobj == null||clientobj.size() == 0) {
            log.info("[接口模块]认证clientid错误,clientId={}"+clientID);
            resultMap.put("code","101");
            resultMap.put("msg","认证错误:clientId错误");
            return resultMap;
        }

        //2.校验pwd密码,根据redis中的用户密码进行校验
        String pwd = smsInterfaceForm.getPwd();
        if (!pwd.equals(clientobj.get("pwd"))){
            log.info("[接口模块]认证密码错误,pwd={}"+pwd);
            resultMap.put("code","102");
            resultMap.put("msg","认证错误:密码错误");
            return resultMap;
        }

        //3.校验ip,根据redis中预留的用户ip进行校验
        String ip = smsInterfaceForm.getIp();
        //从redis中取出预留的ip地址集合
        String ipaddress = (String) clientobj.get("ipaddress");
        //根据,切割
        String[] ipArray = ipaddress.split(",");
        //ip地址是否校验成功
        boolean flag=false;
        //遍历预留的ip集合
        if (ipArray!=null){
            for (String realip : ipArray) {
               if (ip.equals(realip)){
                   //ip地址正确
                   flag=true;
                   break;
               }
            }
        }
        //如果不正确
        if (!flag){
            log.info("[接口模块]认证ip错误,ip={}"+ip);
            resultMap.put("code","103");
            resultMap.put("msg","认证错误:ip错误");
            return resultMap;
        }

        //4.手机号校验
        //获取用户发送手机号集合
        String mobile = smsInterfaceForm.getMobile();
        String[] mobileArray = mobile.split(",");
        //校验手机号个数
        if (mobileArray .length==0|| mobileArray.length>100) {
            log.info("[接口模块]认证手机号错误,mobile={}"+mobile);
            resultMap.put("code","105");
            resultMap.put("msg","认证错误:手机号错误");
            return resultMap;
        }


        //校验手机号正则
        Set<String> errorMobile=new HashSet<>();
        String regex = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17[013678])|(18[0,5-9]))\\d{8}$";
        for (String phone : mobileArray) {
            if (!phone.matches(regex)){
                //有问题的手机号加入错误手机号集合中
                errorMobile.add(phone);
            }
        }
        //判断错误手机号集合是否有错误的手机号
        if (errorMobile.size()>0){
            log.info("[接口模块]认证手机号错误,errorMobile={}"+errorMobile);
            resultMap.put("code","105");
            resultMap.put("msg","认证错误:手机号错误");
            return resultMap;
        }

        //5.校验下行编码,非空,并且是数字
        String srcIdStr = smsInterfaceForm.getSrcID();
        //尝试转换数字
        Long srcID =null;
        try {
            srcID=Long.parseLong(srcIdStr);
        } catch (NumberFormatException e) {
            log.info("[接口模块]认证下行编吗=码错误,srcID={}"+srcIdStr);
            resultMap.put("code","106");
            resultMap.put("msg","认证错误:下行编号错误");
            return resultMap;
        }

        //6.如果校验成功,封装短信对象发送MQ队列中进行排队消峰
        //根据手机号封装我们平台内部使用的短信对象
        for (String phone : mobileArray) {
            StandardSubmit standardSubmit=new StandardSubmit();
             //这个短信对象的唯一id
            standardSubmit.setSequenceId(String.valueOf(idWorker.nextId()));
            //客户端id
            standardSubmit.setClientID(Integer.parseInt(smsInterfaceForm.getClientID()));
            //发送时间
            standardSubmit.setSendTime(new Date());
            //发送目标手机号
            standardSubmit.setDestMobile(phone);
            //发送内容
            standardSubmit.setMessageContent(smsInterfaceForm.getContent());
            //消息的优先级 0最低 3最高
            standardSubmit.setMessagePriority(Short.parseShort(String.valueOf(clientobj.get("priority"))));
            //设置短线发送方式,协议,一般为http
            standardSubmit.setSource(SourceType.HTTP);
            //客户侧唯一序列号,也就是下行编码
            standardSubmit.setSrcSequenceId(srcID);
            //手机接收的状态码 0成功 1等待 2失败
            standardSubmit.setReportState(ReportStateConstants.WAIT);

            rabbitTemplate.convertAndSend(RabbitMQConstants.TOPIC_PRE_SEND+"_exchange","routingKey",standardSubmit);
        }



        resultMap.put("code","0");
        resultMap.put("msg","接收成功");
        return resultMap;
    }
}
